package org.lzy.shop.util

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.floatPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import java.util.concurrent.ConcurrentHashMap

/**
 * 基于 DataStore 的键值存储工具类
 * 支持多种数据类型（基本类型、String等）
 * 使用 Kotlin Flow 进行异步操作
 */
object DataStoreUtils {
    // 添加常量定义
    private const val USER_DATA_ID = "user_data"
    private const val TOKEN_ID = "token_data"
    private const val DEFAULT_PREFERENCES_NAME = "app_preferences"

    // 为不同数据存储创建单独的DataStore实例
    private val Context.tokenDataStore: DataStore<Preferences> by preferencesDataStore(name = TOKEN_ID)
    private val Context.userDataStore: DataStore<Preferences> by preferencesDataStore(name = USER_DATA_ID)
    private val Context.defaultDataStore: DataStore<Preferences> by preferencesDataStore(name = DEFAULT_PREFERENCES_NAME)

    // 存储所有命名的DataStore实例
    private val dataStoreMap = ConcurrentHashMap<String, DataStore<Preferences>>()

    // 应用上下文
    private lateinit var appContext: Context

    // 协程作用域，用于异步操作
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    // JSON 序列化配置
    val json = Json {
        // 允许处理未知属性，避免因服务端增加字段导致解析失败
        ignoreUnknownKeys = true

        // 使用宽松模式，增加容错性
        isLenient = true

        // 允许将空字符串解析为null
        coerceInputValues = true
    }

    /**
     * 初始化DataStoreUtils
     * 应在Application中调用
     */
    fun init(context: Context) {
        appContext = context.applicationContext
    }

    // ====================== Token相关操作 ======================

    fun putToken(key: String, value: String) {
        val preferencesKey = stringPreferencesKey(key)
        scope.launch {
                try {
                    appContext.tokenDataStore.edit { preferences ->
                        preferences[preferencesKey] = value
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }


        }
    }

    fun getToken(key: String, defaultValue: String = ""): String {
        val preferencesKey = stringPreferencesKey(key)
        return runBlocking {
            try {
                appContext.tokenDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    fun clearTokenData() {
        scope.launch {
            try {
                appContext.tokenDataStore.edit { it.clear() }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    // ====================== 用户数据相关操作 ======================

    fun clearUserData() {
        scope.launch {
            try {
                appContext.userDataStore.edit { it.clear() }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    // ====================== 清除所有数据 ======================

    fun clearAll() {
        scope.launch {
            try {
                appContext.defaultDataStore.edit { it.clear() }
                appContext.tokenDataStore.edit { it.clear() }
                appContext.userDataStore.edit { it.clear() }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    // ====================== 默认实例的读写操作 ======================

    // Boolean 操作
    fun putBoolean(key: String, value: Boolean) {
        val preferencesKey = booleanPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences[preferencesKey] = value
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getBoolean(key: String, defaultValue: Boolean = false): Boolean {
        val preferencesKey = booleanPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // Int 操作
    fun putInt(key: String, value: Int) {
        val preferencesKey = intPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences[preferencesKey] = value
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getInt(key: String, defaultValue: Int = 0): Int {
        val preferencesKey = intPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // Long 操作
    fun putLong(key: String, value: Long) {
        val preferencesKey = longPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences[preferencesKey] = value
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getLong(key: String, defaultValue: Long = 0L): Long {
        val preferencesKey = longPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // Float 操作
    fun putFloat(key: String, value: Float) {
        val preferencesKey = floatPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences[preferencesKey] = value
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getFloat(key: String, defaultValue: Float = 0f): Float {
        val preferencesKey = floatPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // String 操作
    fun putString(key: String, value: String?) {
        val preferencesKey = stringPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    if (value != null) {
                        preferences[preferencesKey] = value
                    } else {
                        preferences.remove(preferencesKey)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getString(key: String, defaultValue: String = ""): String {
        val preferencesKey = stringPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // 序列化对象操作
    inline fun <reified T> putObject(key: String, value: T) {
        try {
            val jsonString = json.encodeToString(value)
            putString(key, jsonString)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    inline fun <reified T> getObject(key: String, defaultValue: T? = null): T? {
        val jsonString = getString(key)
        return if (jsonString.isNotEmpty()) {
            try {
                json.decodeFromString(jsonString)
            } catch (e: Exception) {
                e.printStackTrace()
                defaultValue
            }
        } else {
            defaultValue
        }
    }

    // 移除指定键值对
    fun remove(key: String) {
        val preferencesKey = stringPreferencesKey(key)
        scope.launch {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences.remove(preferencesKey)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    // 判断是否包含指定键
    fun containsKey(key: String): Boolean {
        val preferencesKey = stringPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first().contains(preferencesKey)
            } catch (e: Exception) {
                false
            }
        }
    }

    // 配置数据的String操作 - 使用defaultDataStore
    fun putConfig(key: String, value: String?) {
        val preferencesKey = stringPreferencesKey(key)
        runBlocking {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    if (value != null) {
                        preferences[preferencesKey] = value
                    } else {
                        preferences.remove(preferencesKey)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getConfig(key: String, defaultValue: String = ""): String {
        val preferencesKey = stringPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }

    // 配置数据的Int操作
    fun putConfig(key: String, value: Int) {
        val preferencesKey = intPreferencesKey(key)
        runBlocking {
            try {
                appContext.defaultDataStore.edit { preferences ->
                    preferences[preferencesKey] = value
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun getConfig(key: String, defaultValue: Int = 0): Int {
        val preferencesKey = intPreferencesKey(key)
        return runBlocking {
            try {
                appContext.defaultDataStore.data.first()[preferencesKey] ?: defaultValue
            } catch (e: Exception) {
                defaultValue
            }
        }
    }
}